package com.xrui.hbaseview.converters;

import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.*;

/**
 * This class is a place holder for RegionInfo editors.
 */
public class RegionInfoConverter extends JsonConverter {

    private static final long serialVersionUID = -3479231987593431384L;

    @Override
    public byte[] toBytes(String value) {
        if (value == null) {
            return EMPTY_BYTES_ARRAY;
        }

        RegionInfoWrapper wrapper = fromJson(value, RegionInfoWrapper.class);
        if (wrapper != null) {
            try {
                HRegionInfo info = wrapper.toHRegion();
                ByteArrayOutputStream stream = new ByteArrayOutputStream();

                DataOutput output = new DataOutputStream(stream);
                info.write(output);

                return stream.toByteArray();
            } catch (IOException e) {
                LOG.error("Failed to convert HRegionInfo to byte array.", e);
            }
        }

        return Bytes.toBytes(value);
    }

    @Override
    public String toString(byte[] value) {
        if (value == null) {
            return null;
        }

        try {
            HRegionInfo info = new HRegionInfo();
            info.readFields(new DataInputStream(new ByteArrayInputStream(value)));

            return toJson(new RegionInfoWrapper(info));
        } catch (IOException e) {
            LOG.error("Failed to convert byte array to HRegionInfo.", e);
            return Bytes.toString(value);
        }
    }

    private static class RegionInfoWrapper {

        //  private String  tableName;
        private TableName tableName;
        private String startKey;
        private String endKey;
        private boolean offLine;
        private boolean split;
        private long regionID;

        RegionInfoWrapper(HRegionInfo info) {
            tableName = info.getTable();
            startKey = Bytes.toStringBinary(info.getStartKey());
            endKey = Bytes.toStringBinary(info.getEndKey());
            offLine = info.isOffline();
            split = info.isSplit();
            regionID = info.getRegionId();
        }

        public HRegionInfo toHRegion() {
            HRegionInfo info = new HRegionInfo(
                tableName, Bytes.toBytesBinary(startKey), Bytes.toBytesBinary(endKey), split, regionID);

            info.setOffline(offLine);
            return info;
        }
    }
}
